package com.flmz.friend.service.exam.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.flmz.common.core.constants.Constants;
import com.flmz.common.core.domain.TableDataInfo;
import com.flmz.common.core.utils.ThreadLocalUtil;
import com.flmz.friend.domain.exam.dto.ExamQueryDTO;
import com.flmz.friend.domain.exam.dto.ExamRankDTO;
import com.flmz.friend.domain.exam.vo.ExamRankVO;
import com.flmz.friend.domain.exam.vo.ExamVO;
import com.flmz.friend.domain.user.vo.UserVO;
import com.flmz.friend.manager.ExamCacheManager;
import com.flmz.friend.manager.UserCacheManager;
import com.flmz.friend.mapper.exam.ExamMapper;
import com.flmz.friend.mapper.user.UserExamMapper;
import com.flmz.friend.service.exam.IExamService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
public class ExamServiceImpl implements IExamService {

	@Autowired
	private ExamMapper examMapper;

	@Autowired
	private ExamCacheManager examCacheManager;

	@Autowired
	private UserCacheManager userCacheManager;

	@Autowired
	private UserExamMapper userExamMapper;

	@Override
	public List<ExamVO> list(ExamQueryDTO examQueryDTO) {
		PageHelper.startPage(examQueryDTO.getPageNum(), examQueryDTO.getPageSize());
		return examMapper.selectExamList(examQueryDTO);
	}

	@Override
	public TableDataInfo redisList(ExamQueryDTO examQueryDTO) {
		// 从redis当中获取竞赛列表的数据
		Long total = examCacheManager.getListSize(examQueryDTO.getType(), null);
		List<ExamVO> examVOList;
		if (total == null || total <= 0) {
			examVOList = list(examQueryDTO); // 从数据库查询
			examCacheManager.refreshCache(examQueryDTO.getType(), null);
			total = new PageInfo<>(examVOList).getTotal();
		} else {
			examVOList = examCacheManager.getExamVOList(examQueryDTO, null);
			total = examCacheManager.getListSize(examQueryDTO.getType(), null);
		}
		if (CollectionUtil.isEmpty(examVOList)) {
			return TableDataInfo.empty();
		}
		// 把用户已经报名的竞赛设为true
		assembleExamVOList(examVOList);
		return TableDataInfo.success(examVOList, total);
	}

	@Override
	public TableDataInfo rankList(ExamRankDTO examRankDTO) {
		Long total = examCacheManager.getRankListSize(examRankDTO.getExamId());
		List<ExamRankVO> examRankVOList;
		if (total == null || total <= 0) {
			PageHelper.startPage(examRankDTO.getPageNum(), examRankDTO.getPageSize());
			examRankVOList = userExamMapper.selectExamRankList(examRankDTO.getExamId());
			examCacheManager.refreshExamRankCache(examRankDTO.getExamId());
			total = new PageInfo<>(examRankVOList).getTotal();
		} else {
			examRankVOList = examCacheManager.getExamRankList(examRankDTO);
		}
		if (CollectionUtil.isEmpty(examRankVOList)) {
			return TableDataInfo.empty();
		}
		assembleExamRankVOList(examRankVOList);
		return TableDataInfo.success(examRankVOList, total);
	}

	@Override
	public String getFirstQuestion(Long examId) {
		// 获取竞赛中题目的顺序列表，先从redis，没有的话就查询数据库
		// 数据类型list  key：e:q:l:examId   value：questionId
		checkAndRefresh(examId);
		return examCacheManager.getFirstQuestion(examId).toString();
	}

	@Override
	public String preQuestion(Long examId, Long questionId) {
		checkAndRefresh(examId);
		return examCacheManager.preQuestion(examId, questionId).toString();
	}

	@Override
	public String nextQuestion(Long examId, Long questionId) {
		checkAndRefresh(examId);
		return examCacheManager.nextQuestion(examId, questionId).toString();
	}

	private void assembleExamVOList(List<ExamVO> examVOList) {
		Long userId = ThreadLocalUtil.get(Constants.USER_ID, Long.class);
		List<Long> userExamIdList = examCacheManager.getAllUserExamList(userId);
		if (CollectionUtil.isEmpty(userExamIdList)) {
			return;
		}
		// 标记用户已经报名的竞赛
		for (ExamVO examVO : examVOList) {
			if (userExamIdList.contains(examVO.getExamId())) {
				examVO.setEnter(true);
			}
		}
	}

	private void assembleExamRankVOList(List<ExamRankVO> examRankVOList) {
		if (CollectionUtil.isEmpty(examRankVOList)) {
			return;
		}
		for (ExamRankVO examRankVO : examRankVOList) {
			Long userId = examRankVO.getUserId();
			UserVO user = userCacheManager.getUserById(userId);
			examRankVO.setNickName(user.getNickName());
		}
	}

	private void checkAndRefresh(Long examId) {
		Long listSize = examCacheManager.getExamQuestionListSize(examId);
		if (listSize == null || listSize <= 0) {
			examCacheManager.refreshExamQuestionCache(examId);
		}
	}
}
